perm filename PK[1,2]14 blob sn#261495 filedate 1977-02-08 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00006 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	PK STRT START0 STRT11 INLOP PRVLIN NXTLIN LAST REWHO0 REWHO REE WRDDON WRDD1 NOTNBR READ1 READ0 FLIP FLIP1
C00011 00003	SPW TENWIN NOTNEG DOPTYJ PTDONE NOJOB NODPYH NOTIN NOTIN1 NOTOUT NOTOU1 NODDB GENINT
C00019 00004	BUFPNT TLOP APNYTR NOTSPE DDSPE DDSPE1 IIISPE IIISP1 TTYSPE NODD TAKR1 TAKR2 NOTAKR PSCRLF PCRLF CTRLBT APNYT LEPRNT
C00027 00005	SIXOUT SIX1 CPOPJ OCTPNT OCT1 OCTNUM DECNUM STRING ST1 DDWRD1 DDWRD2 HEAD DONE DPYBUF LINSET CRLF WHOLIN HEADER TEXT BUFEND
C00029 00006	CHRTBL
C00035 ENDMK
C⊗;
;PK STRT START0 STRT11 INLOP PRVLIN NXTLIN LAST REWHO0 REWHO REE WRDDON WRDD1 NOTNBR READ1 READ0 FLIP FLIP1

	TITLE PK

A←1
B←2
C←3
D←4
E←5
F←6
G←7
H←10
Z←11
DAT←12
SPACE←13
DDB←14
PTR←15
I←16
P←17

CR←←15  LF←←12  TAB←←11  BS←←177  ALT←←175

APLINE←←12  ;ASSOCIATED PRESS LINE NUMBER
NYLINE←←13  ;NY TIMES LINE NUMBER

PDLLEN←←100

TTYTAB←←220
LINTAB←←302
PTYJOB←←270
JOBNAM←←225
LETAB←←237
LEBUF←←330	;Displacement of actual line editor buffer from beginning of dpy hdr
NOSHFL←←263		;REALLY MEMSIZ, BUT 0 IN NON-SHUFFLING SYSTEM

INTTTY←←20000	;LEFT HALF INTERRUPT BIT FOR TTY INPUT

DEFINE PEEK(AC,ADDR)
<	MOVEI AC,ADDR
	CALLI AC,33	;peekuuo
>

LOC 124
REE
RELOC

PDL:	BLOCK PDLLEN
LINNBR:	-1
CONVRT:	-1 ;FLAG: 0 MEANS DON'T CONVERT AP/NYT LINES TO ASCII, -1 MEANS DO CONVERT
APNYTF:	0  ;FLAG: 0 MEANS NOT DOING AP OR NYT LINE OR NOT CONVERTING
	   ;     -1 MEANS CONVERTING AP OR NYT.

INTRPT:	DISMIS			;SIMPLE INTERRUPT MODULE

SCRSIZ:	=40-=12			;NUMBER OF LINES ON DISPLAY SCREEN MINUS TITLES
	=42-=12			;III
	=40-=12			;DD
	=24-=12			;DM

MINTOP:	=9
	=9			;III
	=9			;III
	=3			;DM

	JRST FLIP		;START AT SA-1 TO INVERT AP/NYT CONVERSION FLAG
STRT:	SETOM CONVRT		;DEFAULT IS CONVERT AP/NYT LINES TO ASCII
START0:	SETOM LINNBR		;NEVER DONE INITIALIZATION
	RESET
	MOVEI A,INTRPT
	MOVEM A,JOBAPR↑		;INTERRUPT MODULE'S ADDRESS
	OUTSTR[ASCIZ/TTY #?/]
STRT11:	SETZM WHOFLG
	PEEK A,221		;get numbers of: teletypes, IIIs, DDs, PTYs
	MOVE B,[POINT 9,A]
	SETZM MAXTTY#
	ILDB C,B
	ADDM C,MAXTTY		;add up total number of TTYs
	TLNE B,770000
	JRST .-3
	movni	a,1
	setprv	a,
	tlnn	a,1
	exit
	SETZ A,
	INWAIT			;WAIT FOR LINE TO BE TYPED
	SNEAKW B,
	CAIN B,15
	JRST NOTNBR		;IF CRLF, JUST EXIT
INLOP:	INCHWL B		;read in TTY number
	CAIN B,15
	JRST INLOP
	CAIL B,"0"
	CAILE B,"7"
	JRST LAST
	IMULI A,10
	ADDI A,-60(B)
	JRST INLOP
PRVLIN:	SOS A,LINNBR		;PREVIOUS TTY
	HRRZ A,A		;DON'T LET IT BE NEGATIVE
	INCHRW B
	CAIN B,ALT
	MOVEI B,LF
	JRST LAST
NXTLIN:	AOS A,LINNBR		;NEXT TTY
	INCHRW B		;READ THE LF
LAST:	CAMG A,MAXTTY		;LEGAL TTY NUMBER?
	CAIE B,12		;YES, END OF LINE?
	JRST [	CLRBFI
		OUTSTR[ASCIZ/HO HO!
/]
		JRST STRT]
	MOVEM A,LINNBR		;SAVE TTY LINE NUMBER
REWHO0:	SETZM APNYTF		;ASSUME NOT CONVERTING AP/NYT TO ASCII
	SKIPN CONVRT		;WANT TO CONVERT?
	JRST REWHO		;NO
	CAIE A,APLINE		;IS THIS AP LINE?
	CAIN A,NYLINE
	SETOM APNYTF		;YES, SET FLAG
REWHO:	MOVEM	A,TABENT#
	MOVEM	A,LINENT#
	MOVEM	A,LEENT#
	MOVE	SPACE,A
	TTYJOB	SPACE,		;JOB NUMBER OF USER
	HRLZI	SPACE,(SPACE)
	HRRI	SPACE,WHOLIN	;SO SPW CAN DO WHO UUO WITH OUR AC SPACE
	MOVEM	SPACE,SVSPAC#
	MOVSI	DDB,INTTTY	;INTERRUPT BIT SPW WILL USE TO GENERATE INTERRUPT
	HLROM	SPACE,WHOFLG#	;FLAG SPW WE ARE READY

	SUBI A,121
	MOVEM A,PTYENT#
	PEEK A,TTYTAB
	ADDM A,TABENT		;LOC OF TTYTAB ENTRY FOR TTY OF INTEREST
	PEEK A,LINTAB
	ADDM A,LINENT		;LOC OF LINTAB ENTRY
	PEEK A,LETAB
	SUBI A,20		;Low core pointer is really to LETAB+20
	ADDM A,LEENT		;LOC OF LETAB ENTRY
	PEEK A,LEBUF
	JUMPN A,.+2
	MOVEI A,45	;TEMPORARY KLUDGE IN CASE SYSTEM LOW-CORE VALUE NOT IN YET
	MOVEM A,DLEBUF#		;Displacement of editor buffer from dpy hdr addr
	PEEK A,PTYJOB
	SKIPGE PTYENT		;SKIP IF TTY IS NOT A PTY
	JRST REE
	ADDM A,PTYENT
	PEEK A,JOBNAM
	MOVEM A,JOBTAB#
REE:	PEEK A,NOSHFL
	SKIPE A
	MOVNI A,1
	SETCAM A,NOSHFF#
	PEEK A,37		;GET RMEMSIZ-1
	HRLZ A,A
	JUMPGE A,.+2
	HRRI A,540000
	SKIPE NOSHFF
	HRRI A,0
	SETPR2 A,
	HALT STRT
	MOVEI A,-400000(A)
	MOVNM A,TENADR#
	SPCWAR 'SSW'
	SETZM YET
	SETZM DONE
	SETOM DDDPY#		;ASSUME ON A DD
	SETO A,
	GETLIN A
	CAME A,[-1]
	TLNN A,460000		;DD,III, OR DM?
	JRST [	SETOM NODPY#	;NO
		SETZM DDDPY
		MOVEI A,=67	;2 less than actual max to allow for control bits
		MOVEM A,MAXCOL		;SET MAX LINE LENGTH
		SETZM MINCOL		;NO MIN LINE LENGTH ON TTYS
		MOVE A,[400000,,SPW]	; WE ARE ON A TELETYPE--DO IT ONLY ONCE
		SPCWGO A,
		OUTSTR CRLF
		OUTSTR WHOLIN
		OUTSTR HEADER
		OUTSTR TEXT
		EXIT]
	MOVEI B,0		;ASSUME III
	TLNE A,20000		; -1 FOR TELETYPES, 0 FOR III, 1 FOR DD, 2 FOR DM
	TROA B,1		;DD
	SETZM DDDPY		;NOT DD
	TLNE A,40000
	MOVEI B,2		;DM
	MOVEM B,NODPY
	MOVE A,[=85↔=82↔=78](B)	;2 less than actual max to allow for control bits
	MOVEM A,MAXCOL#		;SET MAX LINE LENGTH
	MOVE A,[=7↔=8↔=28](B)
	MOVEM A,MINCOL#		;SET MIN LINE LENGTH
	MOVE A,WORD1(B)
	MOVEM A,DPYBUF		;INITIALIZE FIRST TWO WORDS OF DISPLAY PROGRAM
	MOVE A,WORD2(B)		; DEPENDING ON DISPLAY TYPE
	MOVEM A,LINSET
	MOVE A,SCRSIZ+1(B)
	MOVEM A,SCRSIZ		;NUMBER OF LINES ON DISPLAY
	MOVE A,MINTOP+1(B)
	MOVEM A,MINTOP		;MINIMUM NUMBER OF LINES USED BEFORE OUTPUT BUFFER
WRDDON:	MOVE A,[400017,,SPW]
	SPCWGO A,		;START SPACEWAR ON PDP-10
	PPACT 0			;SHUT OFF PAGE PRINTER
WRDD1:	MOVSI	A,INTTTY
	INSKIP	1		;Don't wait if line already typed
	IENBW	A,		;WAIT AT INTERRUPT LEVEL UNTIL TTY INPUT

	SPCWAR	'SSW'		;STOP SPACEWAR PROCESS
	SETZM	A,
	SLEEP	A,
;	SKIPE	DONE		;MAKE SURE ALL DD TRANSFERS HAVE FINISHED
;	JRST	.-2
	DPYOUT	[1000,,0↔0]	;Wait for DD, flush DM output

	MOVE	A,LINNBR	;SET UP LINE NUMBER OF TTY WE ARE PEEKING
	SNEAKS			;SKIP IF ANY CHARACTER
	JRST	REWHO
	ANDI	177
	CAIL	"0"
	CAILE	"9"
	JRST	.+2
	JRST	STRT11		;HE TYPED ANOTHER TTY NUMBER
	CAIN	LF
	JRST	NXTLIN		;PEEK AT NEXT TTY
	CAIN	ALT
	JRST	PRVLIN		;PEEK AT PREVIOUS TTY
	CAIE	CR
	JRST	READ0		;DON'T READ LINE--LEAVE IN INPUT BUFFER
NOTNBR:	INCHRW			;READ CR
READ1:	INCHRW
READ0:	PPSEL	0
	PGACT	0
	EXIT	1,
FLIP1:	SKIPL	A,LINNBR	;SKIP IF NEVER INITIALIZED
	JRST	REWHO0
	JRST	START0

FLIP:	SETCMM	CONVRT		;INVERT FLAG FOR CONVERSION OF AP/NYT LINES TO ASCII
	JRST	FLIP1
;SPW TENWIN NOTNEG DOPTYJ PTDONE NOJOB NODPYH NOTIN NOTIN1 NOTOUT NOTOU1 NODDB GENINT

DEVNAM←←0
DEVCHR←←1
DEVIOS←←2
DEVMOD←←4
DEVLOG←←5
DEVBUF←←6
ACTBTS←←11
TTIBUF←←16
TTOBUF←←25
TISYNC←←24

BUF←←0
PUTR←←1
TAKR←←3

DEFINE INC(N)
<	REPEAT N,<IDPB SPACE,PTR
>>

DEFINE PUT(CHR)
<	MOVEI A,CHR
	IDPB A,PTR
>

SPW:	AOSL YET#
	SKIPE DONE
	DISMIS			;NOT DONE YET
	MOVNI A,4
	MOVEM A,YET		;DISMISS IMMEDIATELY 3 OUT OF 4 TIMES SPW IS RUN
	SETZM LINENO		;NUMBER OF OUTPUT LINES GENERATED FROM BUFFER
	MOVE P,[IOWD PDLLEN,PDL];GET STACK

	CONSO 120,1B27		;SKIP IF PDP-6
	JRST [	MOVE I,TENADR	;10 IS EASY!
		JRST TENWIN]
	TLO 2,777000		;INFINITE PROT.
	DATAO 2			;SET IT
	MOVNS I,2		;GET INDEX
TENWIN:	MOVE PTR,[POINT 7,TEXT]	;BYTE POINTER FOR TEXT
	MOVEI SPACE,40
	MOVE DDB,TABENT		;GET LOC OF TTY'S TTYTAB ENTRY
	ADDI DDB,(I)		;UNRELOCATE IT
	MOVE DDB,(DDB)		;GET DDB ADDRESS FROM TTYTAB
	MOVEM DDB,TTYDDB#	;Save for printing

	MOVE B,LEENT
	ADDI B,(I)
	MOVE B,(B)
	MOVEM B,DPYHDR#		;Save dpy header for printing

	MOVEI B,1
	MOVEM B,WHOLIN
	MOVE B,[WHOLIN,,WHOLIN+1]
	BLT B,WHOLIN+LWHO-1

	JUMPE DDB,NODDB
	ADDI DDB,(I)		;ADDRESS OF DDB
	MOVE B,DEVNAM(DDB)	;DEVICE NAME
	PUSHJ P,SIXOUT
	INC 2
	MOVE B,DEVLOG(DDB)
	PUSHJ P,SIXOUT
	INC 2
	MOVE B,DEVCHR(DDB)
	PUSHJ P,OCTPNT
	INC 2
	MOVE B,DEVIOS(DDB)
	PUSHJ P,OCTPNT
	INC 2
	MOVE B,DEVMOD(DDB)
	PUSHJ P,OCTPNT
	INC 2
	MOVE B,LINENT		;GET LOC OF TTY'S LINTAB ENTRY
	ADDI B,(I)
	MOVE B,(B)		;GET LINE CHARACTERISTICS
	PUSHJ P,OCTPNT
	INC 2
	SKIPL TISYNC(DDB)
	JRST NOTNEG
	PUT "-"
NOTNEG:	MOVM A,TISYNC(DDB)
	PUSHJ P,OCTNUM
	SKIPL PTYENT
	JRST DOPTYJ
	MOVEI B,[ASCIZ/ 
/]
;	PUSHJ P,STRING
	JRST PTDONE
DOPTYJ:	MOVEI B,[ASCIZ/ 
PTYJOB:  /]
	PUSHJ P,STRING
	MOVE B,PTYENT
	ADDI B,(I)
	MOVE A,(B)
	PUSH P,A
	PUSHJ P,DECNUM
	MOVEI B,[ASCIZ/  /]
	PUSHJ P,STRING
	POP P,A
	ADD A,JOBTAB
	ADDI A,(I)
	MOVE B,(A)
	PUSHJ P,SIXOUT
PTDONE:	HLLZ B,DEVCHR(DDB)
	LSH B,-=30
	TRNN B,77		;ANY JOB THERE?
	JRST NOJOB		;NO
	SKIPL A,WHOFLG#
	JRST NOJOB
	CAIE B,(A)		;RIGHT JOB?
	JRST GENINT		;NO, WAKE UP MAIN JOB

	MOVE SPACE,SVSPAC
	WHO SPACE,		;GET WHOLINE FOR USER OF THIS TTY, IF ANY SUCH JOB
	MOVEI SPACE,40
NOJOB:	MOVEI B,[ASCIZ/ 
TTYTAB & LETAB: /]
	PUSHJ P,STRING
	MOVE B,TTYDDB
	PUSHJ P,OCTPNT
	INC 2
	MOVE B,DPYHDR
	PUSHJ P,OCTPNT
	MOVEI B,[ASCIZ/
ACTBITS:        /]
	PUSHJ P,STRING
	MOVE B,ACTBTS(DDB)
	PUSHJ P,OCTPNT
	INC 2
	MOVE B,ACTBTS+1(DDB)
	PUSHJ P,OCTPNT
	INC 2
	MOVE B,ACTBTS+2(DDB)
	PUSHJ P,OCTPNT
	INC 2
	MOVE B,ACTBTS+3(DDB)
	PUSHJ P,OCTPNT
;	SKIPE FLAG		;DOING INPUT BUFFER OR OUTPUT BUFFER?
;	JRST NOTIN		;OUTPUT
	SKIPN DAT,DPYHDR
	JRST NODPYH
	MOVEI B,[ASCIZ/
 
LINE EDITOR:
/]
	PUSHJ P,STRING
	ADD DAT,DLEBUF		;Point to buffer itself
	ADDI DAT,(I)		;Unrelocate it
	HRLI DAT,440700
	MOVE F,DAT		;Make copy of byte pointer for LEPRNT
	MOVEI A,1
	TDNE A,(DAT)		;Is this a text word?
	AOJA DAT,.-1		;Yes
	CAMN F,DAT
	JRST NODPYH		;Empty line editor
	SUBI DAT,1		;Point to last real text word in buffer
	HRLI DAT,100700		;Byte pointer to char before EOLCHR in buffer
	MOVEM DAT,SPUTR		;Make LEPRNT stop just before he gets to EOLCHR
	MOVEM DAT,STOPR		;Don't ever stop
	SETOM STAKR		;Don't ever print TAKR
	PUSHJ P,LEPRNT
	MOVEI B,[ASCIZ/<eol>/]
	PUSHJ P,STRING
NODPYH:	MOVEI B,[ASCIZ/ 
 
INPUT BUFFER:
/]
	PUSHJ P,STRING
	MOVEI DAT,TTIBUF(DDB)
	PUSHJ P,BUFPNT
NOTIN:	SKIPGE NODPY		;SKIP UNLESS ON TTY
	JRST NOTIN1
	SKIPA B,LINENO
	PUSHJ P,PSCRLF		;PUT OUT BLANK LINE
	CAMGE B,MINTOP		;Use at least 9 lines for Input buffer & line ed.
	AOJA B,.-2
NOTIN1:	MOVEI B,[ASCIZ/ 
 
OUTPUT BUFFER:
/]
	PUSHJ P,STRING
	MOVEI DAT,TTOBUF(DDB)
	PUSHJ P,BUFPNT
NOTOUT:	SKIPG NODPY		;PUT OUT BLANK LINES IF DD OR DM OUTPUT
	JRST NOTOU1
	MOVE A,SCRSIZ		;NUMBER OF LINES ON SCREEN MINUS NBR USED FOR TITLES
	SKIPE DPYHDR
	SUBI A,2		;Two more "title" lines if there is a dpy header
	SUB A,LINENO		;CALC NUMBER OF BLANK LINES NEEDED
	SKIPLE A
	PUSHJ P,PSCRLF		;PUT OUT BLANK LINE WITH ONLY A SPACE ON IT
	SOJG A,.-1
NOTOU1:	MOVEI A,0
	IDPB A,PTR		;Fill out word with nulls (w/at least one null)
	TLNE PTR,760000
	JRST .-2
	JRST 2,@[.+1]
	MOVEI A,2(PTR)
	SUBI A,DPYBUF		;CALC WORD COUNT
	MOVEM A,HEAD+1
	MOVEI A,1
	IORM A,@LASTCLOBBERED#
	SETZM 1(PTR)
	MOVEI A,1(PTR)
	MOVEM A,LASTCLOBBERED
	SKIPL NODPY
	DPYOUT HEAD
	DISMIS

NODDB:	MOVE B,LINNBR		;PRINT LINE NUMBER
	PUSHJ P,OCTPNT
	MOVEI A,=46
	IDPB SPACE,PTR
	SOJG A,.-1
	MOVE B,LINENT		;GET LOC OF TTY'S LINTAB ENTRY
	ADDI B,(I)
	MOVE B,(B)		;GET LINE CHARACTERISTICS
	PUSHJ P,OCTPNT
	MOVEI B,[ASCIZ/ 
 
 
 
 
****** NO DDB POINTER ******
 
 
 
 
/]
	PUSHJ P,STRING
	JRST NOTOUT

GENINT:	SETZM	WHOFLG
	JRST	2,@[.+1]
	INTIPI	[0↔INTTTY,,0]	;SEND OUR MAIN JOB AN INTERRUPT
	JRST	NOJOB		;ERROR RETURN
	JRST	NOJOB
;BUFPNT TLOP APNYTR NOTSPE DDSPE DDSPE1 IIISPE IIISP1 TTYSPE NODD TAKR1 TAKR2 NOTAKR PSCRLF PCRLF CTRLBT APNYT LEPRNT

BUFPNT:	MOVE E,DEVCHR(DDB)
	ANDI E,3777		;GET BUFFER SIZE
	ADD E,BUF(DAT)
	ADDI E,(I)
	HRRZM E,STOPR#		;ADDRESS OF END OF BUFFER
	MOVE F,PUTR(DAT)
	ADDI F,(I)
	TLZ F,1
	MOVEM F,SPUTR#		;PUTR
	MOVE A,TAKR(DAT)
	ADDI A,(I)
	TLZ A,1
	MOVEM A,STAKR#		;TAKR
LEPRNT:	MOVEI C,13		;SYMBOL FOR CONTROL BIT
	MOVEI D,14		;SYMBOL FOR META BIT
	MOVEI G,177
	SETZB H,SPECIAL#	;H IS COLUMN POSITION, SPECIAL IS A FLAG FOR CR/LF
	SKIPL NODPY		;ON TTY?
	JRST TLOP
	MOVEI C,"$"		;YES, USE DIFFERENT SYMBOLS FOR CONTROL AND META
	MOVEI D,"%"
TLOP:	IBP F
	HRRZ A,F
	CAML A,STOPR		;HAVE WE RUN OFF END OF BUFFER?
	JRST [	HRR F,BUF(DAT)	;YES--MOVE BACK TO FRONT OF BUFFER
		ADDI F,1(I)
		TLZ F,1
		HRRZ A,SPUTR
		CAIL A,(F)	;PUTR AT FRONT?
		JRST .+1
		MOVE F,SPUTR	;FORCE MATCH TO BEGINNING
		JRST NODD]	;NOW GO CHECK FOR TAKR
	LDB A,F			;GET A CHAR
	JUMPE A,NODD		;IGNORE NULLS
	SKIPE B,APNYTF#		;ARE WE CONVERTING AP/NYT LINES TO ASCII?
	JRST APNYT		;YES, DO IT
APNYTR:	MOVE B,A		;COPY CHARACTER
	ANDI B,177		; WITHOUT CONTROL BITS
	CAML H,MAXCOL#		;LINE TOO LONG?
	PUSHJ P,PCRLF		;YES--PUT OUT CRLF
	SKIPGE NODPY		;SKIP UNLESS TTY
	JRST TTYSPE
	CAIE B,LF
	CAIN B,CR
	JRST [	SETOM SPECIAL	;got a cr or a lf
		PUSHJ P,CTRLBT	;PUT OUT CONTROL AND META BITS IF ON
		SKIPE DDDPY
		JRST DDSPE	;DD
		SKIPE NODPY
		JRST DMSPE	;DM
		JRST IIISPE]	;III
	SKIPL SPECIAL#		;WAS LAST CHAR A CR OR LF?
	JRST NOTSPE		;NO
	CAML H,MINCOL#		;YES--TOO LITTLE ON THIS LINE?
	PUSHJ P,PCRLF		;NO--PUT OUT CRLF
	SETZM SPECIAL
NOTSPE:	PUSHJ P,CTRLBT		;PUT OUT CONTROL AND META BITS IF ON
	SKIPG DDDPY		;SKIP IF DD
	JRST IIISP1		;DM OR III
	CAIE B,TAB
DMSPE1:	CAIN B,BS
DDSPE:	IDPB G,PTR		;PUT OUT A 177
DDSPE1:	IDPB B,PTR		;PUT OUT CHAR FROM BUFFER
	AOJA H,NODD

DMSPE:	CAIN B,CR
	MOVEI B,4		;CR BECOMES BOLD d
	CAIN B,LF
	MOVEI B,5		;LF BECOMES BOLD e
	JRST DDSPE1

IIISPE:	CAIN B,CR
	MOVEI B,"|"		;CR BECOMES VERTICAL BAR
	CAIN B,LF
	MOVEI B,"↓"		;LF BECOMES DOWN ARROW
	JRST DDSPE1

IIISP1:	CAIN B,TAB
	MOVEI B,"\"		;TAB BECOMES BACKSLASH
	SKIPE NODPY
	JRST DMSPE1		;DM
	JRST DDSPE1		;III

TTYSPE:	PUSHJ P,CTRLBT		;PRINT CONTROL BITS IF PRESENT
	CAIE B,LF
	ADDI H,1		;MOVE OVER ONE COLUMN UNLESS LF OR CR
	CAIN B,CR
	SETZ H,			;BACK AT LEFT MARGIN IF CR
	JUMPE B,NODD		;NO NULLS IF ON TTY
	IDPB B,PTR

NODD:	CAME F,STAKR
	JRST NOTAKR
	SKIPL NODPY
	JRST TAKR1		;DD OR III OR DM
	CAIN B,15		;HERE FOR TTYS ONLY
	JRST [	MOVEI B,12	;DONT SPLIT UP A CR AND A LF--PUT THE LF BACK IN
		IDPB B,PTR
		JRST .+1]
TAKR1:	ADDI H,=12		;COUNT CHARS IN FOLLOWING STRING
	CAMGE H,MAXCOL		;LINE TOO LONG?
	JRST TAKR2
	PUSHJ P,PCRLF
	ADDI H,=12		;COUNT CHARS ON NEW LINE
TAKR2:	MOVEI B,[ASCIZ/||||TAKR||||/]
	PUSHJ P,STRING
	SETZM SPECIAL		;NOTE THAT WE HAVEN'T JUST SEEN A CR OR LF

NOTAKR:	CAME F,SPUTR
	JRST TLOP
	POPJ P,

PSCRLF:	MOVEI Z," "		;INSERT A SPACE AND A CRLF
	IDPB Z,PTR
PCRLF:	MOVEI Z,CR		;INSERT CRLF
	IDPB Z,PTR
	MOVEI Z,12
	IDPB Z,PTR
	SETZ H,			;NOTE BEGINNING NEW LINE
	AOS LINENO#
	POPJ P,

CTRLBT:	TRZE A,200		;CONTROL BIT ON?
	JRST [IDPB C,PTR↔AOJA H,.+1]	;YES
	TRZE A,400		;META BIT ON?
	JRST [IDPB D,PTR↔AOJA H,.+1]	;YES
	POPJ P,

APNYT:	CAILE A,100
	SKIPA A,["?"]		;ILLEGAL CHAR
	MOVE A,CHRTBL(A)	;CONVERT CHARACTER TO ASCII
	JRST APNYTR
;SIXOUT SIX1 CPOPJ OCTPNT OCT1 OCTNUM DECNUM STRING ST1 DDWRD1 DDWRD2 HEAD DONE DPYBUF LINSET CRLF WHOLIN HEADER TEXT BUFEND

SIXOUT:	MOVEI C,6
SIX1:	SETZ A,
	LSHC A,6
	ADDI A,40
	IDPB A,PTR
	SOJG C,SIX1
CPOPJ:	POPJ P,

OCTPNT:	MOVEI C,=12
OCT1:	SETZ A,
	LSHC A,3
	ADDI A,60
	IDPB A,PTR
	SOJG C,OCT1
	POPJ P,

OCTNUM:	IDIVI A,10
	HRLM B,(P)
	JUMPE A,.+2
	PUSHJ P,OCTNUM
	HLRZ A,(P)
	ADDI A,60
	IDPB A,PTR
	POPJ P,

DECNUM:	IDIVI A,=10
	HRLM B,(P)
	JUMPE A,.+2
	PUSHJ P,DECNUM
	HLRZ A,(P)
	ADDI A,60
	IDPB A,PTR
	POPJ P,

STRING:	HRLI B,(<POINT 7,0>)
ST1:	ILDB A,B
	JUMPE A,CPOPJ
	IDPB A,PTR
	JRST ST1

DEFINE CW(C1,B1,C2,B2,C3,B3)
{	<BYTE(8)<B1>,<B2>,<B3>(3)<C1>,<C2>,<C3>>!4	}

WORD1:	0			;III
	CW	1,46,2,0,3,1	;DD
	0			;DM

WORD2:	BYTE(11)<-1000>,670(3)0,0(2)1,2(4)6
	CW	3,1,4,1,5,10
	BYTE(7)177,14,140,142	;DM

HEAD:	640000,,DPYBUF
	0
DONE:	0
	LINSET

LWHO←←=22
DPYBUF:	0
LINSET:	0
CRLF:	ASCID/ 
/
WHOLIN:	REPEAT LWHO,<1>
HEADER:	ASCID/DEVNAM  DEVLOG  DEVCHR        DEVIOS        DEVMOD        LINTAB        TISYNC
/
	1
TEXT:	REPEAT 600,<1>
BUFEND:	1
	0
;CHRTBL

CHRTBL:	"!"			;0: null
	"e"	;1
	LF			;2: elevate→line feed
	"a"	;3
	" "	;4: space
	"s"	;5
	"i"	;6
	"u"	;7
	CR			;10: carriage return
	"d"	;11
	"r"	;12
	"j"	;13
	"n"	;14
	"f"	;15
	"c"	;16
	"k"	;17
	"t"	;20
	"z"	;21
	"l"	;22
	"w"	;23
	"h"	;24
	"y"	;25
	"p"	;26
	"q"	;27
	"o"	;30
	"b"	;31
	"g"	;32
	"{"			;33: shift
	"m"	;34
	"x"	;35
	"v"	;36
	"}"			;37: unshift

	"β"			;40: thin space
	"3"	;41
	"←"			;42: paper feed
	"$"	;43
	"α"			;44: add thin space
	TAB			;45: em space
	"8"	;46
	"7"	;47
	"'"	;50
	"-"	;51
	"4"	;52
	"π"			;53: bell
	","	;54: comma
	"∀"			;55: undefined
	"→"			;56: en space
	"↔"			;57: quad right
	"5"	;60
	")"	;61
	"⊗"			;62: em space
	"2"	;63
	"∞"			;64: em leader
	"6"	;65
	"0"	;66
	"∂"			;67: en leader
	"9"	;70
	"∧"			;71: upper rail
	";"	;72
	"∨"			;73: lower rail
	"."	;74: period
	"1"	;75
	"∃"			;76: undefined
	BS			;77: rub out
	"@"			;100: tape feed

	END	STRT